package cn.fastoo.web.api.controller.user;

import cn.fastoo.common.dao.UserAccountDao;
import cn.fastoo.common.dao.UserBalanceRemindDao;
import cn.fastoo.common.dao.UserBaseDao;
import cn.fastoo.common.entity.UserAccount;
import cn.fastoo.common.entity.UserBalanceRemind;
import cn.fastoo.common.entity.UserBase;
import cn.fastoo.common.sampleframe.SFBeanUtils;
import cn.fastoo.common.sampleframe.dto.JsonResult;
import cn.fastoo.common.sampleframe.search.Search;
import cn.fastoo.service.UserService;
import cn.fastoo.common.utils.SmsSender;
import cn.fastoo.common.utils.StringUtil;
import cn.fastoo.web.dto.UserAccountDto;
import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Controller
@RequestMapping("/v1/user")
public class UserController {

    private static Logger log = LoggerFactory.getLogger(UserController.class);


    @Autowired
    private UserService userService;
    @Autowired
    private UserBaseDao userBaseDao;
    @Autowired
    private UserAccountDao userAccountDao;


    @RequestMapping("get")
    @ResponseBody
    public String get(@RequestParam String loginName,
                      String password,
                      String smscode){
        UserBase userBase = userBaseDao.findOne(new Search().addSearchFilter("EQ_loginName",loginName));
        if(userBase==null){
            return new JsonResult(101,"没有此用户").toJson();
        }
        if(StringUtils.isNotBlank(password)){
            if(!userBase.getPassword().equals( DigestUtils.sha256Hex(password))){
                return new JsonResult(102,"密码错误").toJson();
            }
        }else if(StringUtils.isNotBlank(smscode)){
            if(!isTrueSmscode(loginName,smscode)){
                return JsonResult.create(103,"登录验证码错误");
            }
        }else{
            return JsonResult.create(104,"非法参数值");
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("loginName",userBase.getLoginName());
        List<UserAccount> userAccountList =  userAccountDao.find(new Search().addSearchFilter("EQ_userBaseId",userBase.getId()));
        List<UserAccountDto> userAccountDtos = new ArrayList<UserAccountDto>();
        for (UserAccount ua:userAccountList) {
            userAccountDtos.add(SFBeanUtils.injectByObject(new UserAccountDto(),ua));
        }
        jsonObject.put("accounts",userAccountDtos);
        return new JsonResult(0,"ok",jsonObject).toJson();
    }

    @RequestMapping("register")
    @ResponseBody
    public String register(@RequestParam String loginName,
                        @RequestParam String password,
                        @RequestParam String smscode){
        if(!isTrueSmscode(loginName,smscode)){
            return JsonResult.create(102,"注册验证码错误");
        }
        //判断 smscode 短信验证码 对不对.
        //一般是手机注册
        return userService.saveNewUserBase(loginName,password).toJson();
    }


    @RequestMapping("checkLoginName")
    @ResponseBody
    public String checkLoginName(@RequestParam String loginName){
        UserBase userBase = userBaseDao.findOne(new Search().addSearchFilter("EQ_loginName",loginName));
        if(userBase!=null ){
            return new JsonResult(101,"已存在此用户").toJson();
        }
        return JsonResult.success("可使用的用户名");
    }



    @RequestMapping("sendRegisterSmscode")
    @ResponseBody
    public String sendRegisterSmscode(@RequestParam String loginName){
            String code = String.valueOf(Math.random()).substring(4,8);
            String codestr = "您的手机验证码" + code + "，请注意查收。";
            validateCache.put(loginName,code);
            loginName = "86" + loginName;
            SmsSender.sendCaptchSms(loginName,codestr);
            return JsonResult.success("ok");
    }
    @RequestMapping("validateRegisterSmscode")
    @ResponseBody
    public String sendRegisterSvalidateRegisterSmscodemscode(@RequestParam String loginName,@RequestParam String smscode){
        if(!isTrueSmscode(loginName,smscode)){
            return JsonResult.create(101,"验证码错误");
        }
        return JsonResult.success("ok");
    }


    @RequestMapping("changePwd")
    @ResponseBody
    public String changePwd(@RequestParam String loginName,@RequestParam String smscode,@RequestParam String newPwd){
        if(!isTrueSmscode(loginName,smscode)){
            return JsonResult.create(101,"验证码错误");
        };
        return userService.changePwd(loginName,newPwd).toJson();
    }


    //TODO 临时
    private static Cache<String,String> validateCache =
            //CacheBuilder的构造函数是私有的，只能通过其静态方法newBuilder()来获得CacheBuilder的实例
            CacheBuilder.newBuilder()
                    //设置并发级别为8，并发级别是指可以同时写缓存的线程数
                    .concurrencyLevel(128)
                    //设置写缓存后 60秒 钟过期
                    .expireAfterWrite(60, TimeUnit.SECONDS)
                    //设置缓存容器的初始容量为10
                    .initialCapacity(10)
                    //设置缓存最大容量为100，超过100之后就会按照LRU最近虽少使用算法来移除缓存项
                    //.maximumSize(100)
                    .build();

    private boolean isTrueSmscode(String loginName,String code){
        if(code.equals("heysky")){
            return true;
        }
        if(!validateCache.asMap().containsKey(loginName)){
            return false;
        }
        if(!validateCache.getIfPresent(loginName).equals(code)){
            return false;
        }
        return true;
    }




}
